% Esta funcion calcula los polos para una plantilla (La salida es el filtro NORMALIZADO! wp=1)
% Si le entra un n=0 significa que el usuario no especifico el n y la funcion calcula el optimo.
% Si le entra un n, se hace el filtro NORMALIZADO con ese n (Puede o no respetar la plantilla y el unico dato necesario sera el Ap)
% Ap y Aa estan en dB.
function [ceros, polos, Q] = filter_chevyshev_inv (wp, Ap, wa, Aa, n, n_min, Q, filter_type, wpm, wam)

%% calculo epsilon, n (si no fue espesificado) y a
epsilon=1/sqrt(10^(Aa/10)-1);

if (n == 0)
    switch filter_type
        case 1,
        wpn=wp/wa;
        case 2,
        wpn=wa/wp;
        case 3,
        wpn=(wpm-wp)/(wam-wa);
        case 4,
        wpn=(wam-wa)/(wpm-wp);
    end  
    n=ceil(acosh(1/(epsilon*sqrt(10^(Ap/10)-1)))/acosh(1/wpn));
end
if (Q~=0)
    Q2=0;
    n=0;
    while (Q2 <= Q)
    n=n+1;
    Q2=(1/2)*sqrt(1+(1/(tan(pi*(2*n-1)/(2*n))*tan(asinh(1/epsilon)/n)))^2);
    end 
    n=n-1;
end
if (n>n_min && n_min~=0)
    n=n_min;
end
a=asinh(1/epsilon)/n;

%% inicializacion variables
sigma=zeros(1,n);
w=zeros(1,n);
if (mod(n,2))
    ceros=zeros(1,n-1);
else ceros=zeros(1,n);
end
k2=1;


%% calcula los polos y ceros
for k=1:n
    titas=(2*k-1)*pi/(2*n);
    sigma(k)=-sin(titas)*sinh(a);
    w(k)=cos(titas)*cosh(a);
    
    if (k~=ceil(n/2) && mod(n,2))
        ceros(k2)=1/cos(titas);
        k2=k2+1;
    end
end

w0=sqrt(sigma.*sigma + w.*w);

alpha=sigma./(w0.*w0);
beta=-w./(w0.*w0);


polos=alpha+1i*beta;

Q=abs(w0./(2*sigma));

end